package com.ticket.sass.admin.business.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ticket.sass.admin.business.CommodityCloudPrinterBusiness;
import com.ticket.sass.admin.dto.input.printer.CommodityCloudPrinterAddInput;
import com.ticket.sass.admin.dto.input.printer.CommodityCloudPrinterListInput;
import com.ticket.sass.admin.dto.input.printer.CommodityCloudPrinterUpdInput;
import com.ticket.sass.admin.dto.output.printer.CommodityCloudPrinterListOutput;
import com.ticket.sass.admin.model.LabModel;
import com.ticket.sass.admin.model.PageModel;
import com.ticket.sass.admin.service.impl.CommodityCloudPrinterHallMapServiceImpl;
import com.ticket.sass.admin.service.impl.CommodityCloudPrinterServiceImpl;
import com.ticket.sass.admin.service.impl.HallServiceImpl;
import com.ticket.sass.admin.util.EscapeUtil;
import com.ticket.sass.admin.util.GsonUtil;
import com.ticket.sass.admin.util.ModelUtil;
import com.ticket.sass.common.entity.tenant.CommodityCloudPrinterEntity;
import com.ticket.sass.common.entity.tenant.CommodityCloudPrinterHallMapEntity;
import com.ticket.sass.common.entity.tenant.HallEntity;
import com.ticket.sass.common.exception.enums.ErrorCode;
import com.ticket.sass.common.exception.exception.BadRequestException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ywb
 * @date 2024-04-08 11:25
 */
@Slf4j
@Service
@AllArgsConstructor
public class CommodityCloudPrinterBusinessImpl implements CommodityCloudPrinterBusiness {
    final ModelUtil modelUtil;
    final HallServiceImpl hallService;
    final CommodityCloudPrinterServiceImpl service;
    final CommodityCloudPrinterHallMapServiceImpl commodityCloudPrinterHallMapService;
    
    @Override
    public PageModel<CommodityCloudPrinterListOutput> list(CommodityCloudPrinterListInput input) {
        // 查询打印机信息
        IPage<CommodityCloudPrinterEntity> page = service.iPage(input);
        List<CommodityCloudPrinterListOutput> outputs = page.getRecords().stream().map(CommodityCloudPrinterListOutput::new).collect(Collectors.toList());
        // 批量查询影厅信息
        List<Long> printerIds = outputs.stream().map(CommodityCloudPrinterListOutput::getId).collect(Collectors.toList());
        Map<Long, List<HallEntity>> hallMap = getHallsByPrinterIds(printerIds);
        
        // 将影厅信息与打印机信息合并
        for (CommodityCloudPrinterListOutput output : outputs) {
            List<LabModel> halls = hallMap.getOrDefault(output.getId(), Collections.emptyList())
                .stream()
                .map(hall -> new LabModel(hall.getId(), hall.getName()))
                .collect(Collectors.toList());
            output.setHalls(halls);
        }
        
        return new PageModel<>(page.getTotal(), outputs);
    }
    
    @Override
    public void add(CommodityCloudPrinterAddInput input) {
        // 保存打印机信息
        CommodityCloudPrinterEntity printerEntity = new CommodityCloudPrinterEntity(
            input.getName(),
            input.getType(),
            GsonUtil.toJsonString(input.getData()),
            input.getIsDefault()
        );
        service.save(printerEntity);
        
        commodityCloudPrinterHallMapService.saveRelations(printerEntity.getId(), input.getHallIds(), "printer_id", "hall_id");

        if (input.getIsDefault()){
            service.update(new UpdateWrapper<CommodityCloudPrinterEntity>().notIn("id", printerEntity.getId()).set("is_default", Boolean.FALSE));
        }
    }
    
    @Override
    public void upd(CommodityCloudPrinterUpdInput input) {
        validateId(input.getId());
        
        CommodityCloudPrinterEntity printerEntity = new CommodityCloudPrinterEntity(
            input.getId(),
            input.getName(),
            input.getType(),
            GsonUtil.toJsonString(input.getData()),
            input.getIsDefault()
        );
        // 更新打印机信息
        service.updateById(printerEntity);
        
        commodityCloudPrinterHallMapService.updateRelations(input.getId(), input.getHallIds(), "printer_id", "hall_id");

        if (input.getIsDefault()) {
            service.update(new UpdateWrapper<CommodityCloudPrinterEntity>().notIn("id", printerEntity.getId()).set("is_default", Boolean.FALSE));
        }
    }
    
    
    public Map<Long, List<HallEntity>> getHallsByPrinterIds(List<Long> printerIds) {
        if (printerIds.size() == 0){
            return new HashMap<>();
        }
        
        // 构建查询条件
        QueryWrapper<CommodityCloudPrinterHallMapEntity> wrapper = new QueryWrapper<>();
        wrapper.in("printer_id", printerIds);
        
        // 查询所有打印机关联的影厅信息
        List<CommodityCloudPrinterHallMapEntity> mappings = commodityCloudPrinterHallMapService.list(wrapper);
        
        // 获取所有影厅ID集合
        List<Long> hallIds = mappings.stream().map(CommodityCloudPrinterHallMapEntity::getHallId).collect(Collectors.toList());
        if (hallIds.size() == 0){
            return new HashMap<>();
        }
        
        // 批量查询所有影厅信息
        List<HallEntity> halls = hallService.listByIds(hallIds);
        
        // 构建打印机ID与关联影厅列表的映射关系
        Map<Long, List<HallEntity>> hallMap = new HashMap<>();
        for (CommodityCloudPrinterHallMapEntity mapping : mappings) {
            hallMap.computeIfAbsent(mapping.getPrinterId(), k -> new ArrayList<>());
            halls.stream()
                .filter(hall -> hall.getId().equals(mapping.getHallId()))
                .findFirst()
                .ifPresent(hall -> hallMap.get(mapping.getPrinterId()).add(hall));
        }
        return hallMap;
    }
    
    private void validateId(Long id) {
        if (service.isEmpty(id)) {
            throw new BadRequestException(
                ErrorCode.RECORD_NOT_EXIST,
                EscapeUtil.errorMessage("id", ErrorCode.RECORD_NOT_EXIST.getReasonPhrase())
            );
        }
    }
}
